from tiles.tile import BlankTile
from settings import BOARD_SETTINGS
import pygame


class Board(object):    
    def __init__(self, defaultTile=BlankTile, x=BOARD_SETTINGS.MAP_SIZE[0], y=BOARD_SETTINGS.MAP_SIZE[1]):
        #self.coords=[[defaultTile for col in xrange(x)] for row in xrange(y)]
        self.coords = []
        for col in xrange(x):
            self.coords.append([])
            for row in xrange(y):
                self.coords[col].append(defaultTile())
    
        self.minX = 0
        self.maxX = x-1
        self.minY = 0
        self.maxY = y-1
        
    def getTile(self, x, y):
    #Returns the tile at coordinate x,y
        try:
            return self.coords[x][y]
        except IndexError: raise CoordinateOutOfBoundsException, "Lookup of failed %s, %s is outside of the max range %s, %s"%(x,y,self.maxX, self.maxY) 
        
    def placeTile(self, x, y, tile):
    #adds a new instance of tile at coordinate x,y
        try:
            self.coords[x][y] = tile.onPlacement(x, y) #sets the x,y for the tile and gets the tile
            return True
        except IndexError: raise CoordinateOutOfBoundsException, "Lookup of failed %s, %s is outside of the max range %s, %s"%(x,y,self.maxX, self.maxY)
        
    def removeTile(self, x, y):
    #sets tile at coordinate x,y to a BlankTile instance
        try:
            self.coords[x][y] = BlankTile()
        except CoordinateOutOfBoundsException: raise        
    
    def save(self):
        pass
    
    def load(self):
        pass
    
    def findTilesofType(self, tile):
    #Returns an array of coordinates of all instances of tile on the board
        coords=[]
        for x in xrange(self.maxX):
            for y in xrange(self.maxY):
                if type(self.getTile(x,y))==type(tile):
                    coords.append((x,y))
        return coords
    
    def getAdjacentNodes(self,x,y):
        adjacentNodes = [(x, y-1 if y-1 >= self.minY else self.maxY),  #Above
                         (x, y+1 if y+1 <= self.maxY else self.minY),  #Below
                         (x-1 if x-1 >= self.minX else self.maxX, y),  #Left
                         (x+1 if x+1 <= self.maxX else self.minX, y)]  #Right
        return adjacentNodes
    
    @classmethod
    def getNodesInRadius(cls, x, y, radius):
        adjacentNodes = [(x,y)]
        if radius > 0:
            for a in xrange(0, radius+1):
                for b in xrange(0, radius+1):
                    if a is 0 and b is 0:
                        pass
                    elif a+b <= radius:
                        if b is 0:
                            adjacentNodes.append((x+a,y))
                            adjacentNodes.append((x-a,y))
                        if a is 0:
                            adjacentNodes.append((x,y+b))
                            adjacentNodes.append((x,y-b))
                        if a and b > 0:
                            adjacentNodes.append((x+a,y+b))
                            adjacentNodes.append((x+a,y-b))
                            adjacentNodes.append((x-a,y+b))
                            adjacentNodes.append((x-a,y-b))
                            
            return adjacentNodes
    @classmethod   
    def getDistance(cls, x1, y1, x2, y2):
    #gets the distance from from x1,y1 to x2,y2
        return abs(x2 - x1) + abs(y2 - y1)
    
    def drawBoard(self):
        screen = pygame.display.get_surface()
        startX = 0
        for x in xrange(self.maxX+1):
            startY = 0
            for y in xrange(self.maxY+1):
                currentTile = self.getTile(x,y)
                tileSurface= currentTile.showTile()
                screen.blit(tileSurface, (startX,startY))
                startY += BOARD_SETTINGS.GRID_SIZE[1]
            startX += BOARD_SETTINGS.GRID_SIZE[0]
        
class CoordinateOutOfBoundsException(Exception):
    pass

class CannotAddTileException(Exception):
    pass